package com.sanley.piss.app.manager.shiro.jwt;

import cn.hutool.core.lang.UUID;
import cn.hutool.crypto.SecureUtil;
import com.gitee.dreamkaylee.jwt.JwtPayload;
import com.gitee.dreamkaylee.jwt.token.SignedWithSecretKeyJwtRepository;
import com.gitee.dreamkaylee.shiro.authz.principal.ShiroPrincipal;
import com.gitee.dreamkaylee.shiro.boot.jwt.JwtPayloadRepository;
import com.gitee.dreamkaylee.shiro.boot.jwt.token.JwtAccessToken;
import com.google.common.collect.Maps;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;

import javax.crypto.SecretKey;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.Base64;
import java.util.Map;

/**
 * @author limk
 * @date 2020/12/23 18:13
 */
public class SinopecJwtPayloadRepository extends JwtPayloadRepository implements InitializingBean {

    private final byte[] base64Secret = Base64.getDecoder().decode("cGFtc0BzaW5vcGVjJnRpbmdzb2Z0IzIwMjAuMTIuMjQ=");

    private SecretKey secretKey = null;

    private final SignedWithSecretKeyJwtRepository signedWithSecretKeyJwtRepository;

    public SinopecJwtPayloadRepository(SignedWithSecretKeyJwtRepository signedWithSecretKeyJwtRepository) {
        super();
        this.signedWithSecretKeyJwtRepository = signedWithSecretKeyJwtRepository;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if(secretKey == null) {
            secretKey = SecureUtil.generateKey("HmacSHA256", base64Secret);
        }
    }

    @Override
    public String issueJwt(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) {
        ShiroPrincipal principal = (ShiroPrincipal) subject.getPrincipal();

        // 利用登陆用户信息构造jwt
        Map<String, Object> claims = Maps.newHashMap();

        claims.put("userId", principal.getUserId());
        claims.put("roles", StringUtils.collectionToCommaDelimitedString(principal.getRoles()));
        claims.put("perms", StringUtils.collectionToCommaDelimitedString(principal.getPerms()));

        String algorithm = "HS256";
        String issuer = "tingsoft";
//        long period = 2 * 60 * 60 * 1000;
        long period = 60 * 1000;
        return signedWithSecretKeyJwtRepository.issueJwt(secretKey, UUID.fastUUID().toString(),
                principal.getUserId(), issuer, principal.getUserId(), claims, algorithm, period);
    }

    @Override
    public boolean verify(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response, boolean checkExpiry) throws AuthenticationException {
        JwtAccessToken jwtToken = (JwtAccessToken) token;
        return signedWithSecretKeyJwtRepository.verify(secretKey, jwtToken.getToken(), checkExpiry);
    }

    @Override
    public JwtPayload getPayload(JwtAccessToken token, boolean checkExpiry) {
        return signedWithSecretKeyJwtRepository.getPayload(secretKey, token.getToken(), checkExpiry);
    }

}
